
#include "Timer.hpp"

// linux api
#include <sys/timerfd.h> //定时器文件描述符

#include <unistd.h>
#include <stdio.h>
#include <string>

#include <iostream>
using namespace std;

namespace tulun
{
    // Timer::
    // using TimerCallback = std::function<void(void)>;
    // m_timerId;
    // TimerCallback m_callback;
    // int tag;                        // 1 一次运行，2 周期运行
    bool Timer::settimer(size_t interval)
    {
        bool ret = true;
        struct itimerspec new_value = {0};
        new_value.it_interval.tv_sec = (interval / 1000);
        new_value.it_value.tv_nsec = (interval % 1000) * 1000 * 1000;
        new_value.it_value = new_value.it_interval;
        if (timerfd_settime(m_timerId, 0, &new_value, nullptr) < 0)
        {
            ret = false;
        }
        return ret;
    }

    Timer::Timer() : m_timerId(-1), m_callback(nullptr)
    {
    }
    Timer::~Timer()
    {
        close_timer();
    }

    bool Timer::init()
    {
        bool ret = true;
        if (m_timerId > 0)
        {
            return ret;
        }
        m_timerId = ::timerfd_create(CLOCK_MONOTONIC, 0);
        if (m_timerId < 0)
        {
            ret = false;
        }
        return ret;
    }
    bool Timer::set_timer(const TimerCallback &cb, size_t interval)
    {
        bool ret = false;
        if (m_timerId > 0 && settimer(interval))
        {
            m_callback = cb;
            ret = true;
        }
        return ret;
    }
    bool Timer::resete_timer(size_t interval)
    {
        bool ret = false;
        if (m_timerId > 0 && m_callback != nullptr && settimer(interval))
        {
            ret = true;
        }
        return ret;
    }
    void Timer::handle_event()
    {
        unsigned long exp_cnt = 0;
        if (read(m_timerId, &exp_cnt, sizeof(exp_cnt)) != sizeof(exp_cnt))
        {
            return;
        }
        if (m_callback != nullptr)
        {
            m_callback();
        }
    }
    size_t Timer::get_TimerId() const { return m_timerId; }
    bool Timer::close_timer()
    {
        bool ret = false;
        if (m_timerId > 0)
        {
            close(m_timerId);
            m_timerId = -1;
            m_callback = nullptr;
            ret = true;
        }
        return ret;
    }

} // namespace tulun